/*
 * FaceCat图形通讯框架
 * 著作权编号:2015SR229355+2020SR0266727
 * 上海卷卷猫信息技术有限公司
 */

#include "../../stdafx.h"
#include "../../include/core/FCTran.h"

namespace FaceCat{
	static HashMap<String, String> m_htmlColors;

	double FCTran::round(double x){     
		int sa = 0, si = 0;  
		if(x == 0.0){
			return 0.0; 
		}
		else{
			if(x > 0.0){
				sa = (int)x;   
				si = (int)(x + 0.5);        
				if(sa == floor((double)si)){
					return sa;    
				}
				else{
					return sa + 1; 
				}
			}       
			else{
				sa = (int)x;   
				si = (int)(x - 0.5);      
				if(sa == ceil((double)si)){
					return sa;       
				}
				else{
					return sa - 1;      
				}
			}
		}
	}

	String FCTran::anchorToStr(const FCAnchor& anchor){
		ArrayList<String> strs;
        if(anchor.left){
            strs.add(L"Left");
        }
        if(anchor.top){
            strs.add(L"Top");
        }
        if(anchor.right){
            strs.add(L"Right");
        }
        if(anchor.bottom){
            strs.add(L"Bottom");
        }
        String anchorStr;
        int size = (int)strs.size();
        if(size > 0){
            for(int i = 0; i < size; i++){
                anchorStr += strs.get(i);
                if(i != size - 1){
                    anchorStr += L",";
                }
            }
        }
        else{
            anchorStr = L"None";
        }
        return anchorStr;
	}

	String FCTran::boolToStr(bool value){
		return value ? L"True" : L"False";
	}

	String FCTran::colorToStr(Long color){
		if(color == FCColor_None){
			return L"None";
		}
        else if (color == FCColor_Back){
            return L"Back";
        }
        else if (color == FCColor_Border){
            return L"Border";
        }
        else if (color == FCColor_Text){
            return L"Text";
        }
        else if (color == FCColor_DisabledBack){
            return L"DisabledBack";
        }
        else if (color == FCColor_DisabledText){
            return L"DisabledText";
        }
		else{
            if (color < FCColor_None)
            {
                return FCTran::longToStr(color);
            }
            else
            {
                int a = 0, r = 0, g = 0, b = 0;
                FCColor::toRgba(0, color, &r, &g, &b, &a);
                wchar_t str[100] = {0};
                if(a == 255){
                    swprintf(str, 99, L"rgb(%d,%d,%d)", r, g, b);
                }else{
                    swprintf(str, 99, L"rgba(%d,%d,%d,%d)", r, g, b, a);
                }
                return str;
            }
		}
	}

	String FCTran::contentAlignmentToStr(FCContentAlignment contentAlignment){
		String str;
        if (contentAlignment == FCContentAlignment_BottomCenter){
            str = L"BottomCenter";
        }
        else if (contentAlignment == FCContentAlignment_BottomLeft){
            str = L"BottomLeft";
        }
        else if (contentAlignment == FCContentAlignment_BottomRight){
            str = L"BottomRight";
        }
        else if (contentAlignment == FCContentAlignment_MiddleCenter){
            str = L"MiddleCenter";
        }
        else if (contentAlignment == FCContentAlignment_MiddleLeft){
            str = L"MiddleLeft";
        }
        else if (contentAlignment == FCContentAlignment_MiddleRight){
            str = L"MiddleRight";
        }
        else if (contentAlignment == FCContentAlignment_TopCenter){
            str = L"TopCenter";
        }
        else if (contentAlignment == FCContentAlignment_TopLeft){
            str = L"TopLeft";
        }
        else if (contentAlignment == FCContentAlignment_TopRight){
            str = L"TopRight";
        }
		return str;
	}

    String FCTran::cursorToStr(FCCursors cursor){
        String str;
        if (cursor == FCCursors_AppStarting){
            str = L"AppStarting";
        }
        else if (cursor == FCCursors_Arrow){
            str = L"Arrow";
        }
        else if (cursor == FCCursors_Cross){
            str = L"Cross";
        }
        else if (cursor == FCCursors_Hand){
            str = L"Hand";
        }
        else if (cursor == FCCursors_Help){
            str = L"Help";
        }
        else if (cursor == FCCursors_IBeam){
            str = L"IBeam";
        }
        else if (cursor == FCCursors_No){
            str = L"No";
        }
        else if (cursor == FCCursors_SizeAll){
            str = L"SizeAll";
        }
        else if (cursor == FCCursors_SizeNESW){
            str = L"SizeNESW";
        }
        else if (cursor == FCCursors_SizeNS){
            str = L"SizeNS";
        }
        else if (cursor == FCCursors_SizeNWSE){
            str = L"SizeNWSE";
        }
        else if (cursor == FCCursors_SizeWE){
            str = L"SizeWE";
        }
        else if (cursor == FCCursors_UpArrow){
            str = L"UpArrow";
        }
        else if (cursor == FCCursors_WaitCursor){
            str = L"WaitCursor";
        }
        return str;
    }

	String FCTran::dockToStr(FCDockStyle dock){
		String str;
		if(dock == FCDockStyle_Bottom){
			str = L"Bottom";
		}
		else if(dock == FCDockStyle_Fill){
			str = L"Fill";
		}
		else if(dock == FCDockStyle_Left){
			str = L"Left";
		}
		else if(dock == FCDockStyle_None){
			str = L"None";
		}
		else if(dock == FCDockStyle_Right){
			str = L"Right";
		}
		else if(dock == FCDockStyle_Top){
			str = L"Top";
		}
		return str;
	}

	String FCTran::doubleToStr(double value){
		wchar_t str[100] = {0};
        swprintf(str, 99, L"%f", value);
		return str;
	}

	String FCTran::floatToStr(float value){
		wchar_t str[100] = {0};
        swprintf(str, 99, L"%f", value);
		return str;
	}

	String FCTran::fontToStr(FCFont *font){
		ArrayList<String> strs;
        strs.add(font->m_fontFamily);
        strs.add(FCTran::getValueByDigit(font->m_fontSize, 1));
        if(font->m_bold){
            strs.add(L"Bold");
        }
        if(font->m_underline){
            strs.add(L"UnderLine");
        }
        if(font->m_italic){
            strs.add(L"Italic");
        }
        if(font->m_strikeout){
            strs.add(L"Strikeout");
        }
        if(font->m_angle != 0){
            strs.add(String(L"Angle=") + FCTran::intToStr(font->m_angle));
        }
        String fontStr;
        int size = (int)strs.size();
        if(size > 0){
            for(int i = 0; i < size; i++){
                fontStr += strs.get(i);
                if(i != size - 1){
                    fontStr += L",";
                }
            }
        }
        return fontStr;
	}

	String FCTran::horizontalAlignToStr(FCHorizontalAlign horizontalAlign){
	    String str;
        if (horizontalAlign == FCHorizontalAlign_Center){
            str = L"Center";
        }
        else if (horizontalAlign == FCHorizontalAlign_Right){
            str = L"Right";
        }
		else if (horizontalAlign == FCHorizontalAlign_Inherit){
            str = L"Inherit";
        }
        else if (horizontalAlign == FCHorizontalAlign_Left){
            str = L"Left";
        }
        return str;
	}

	String FCTran::intToStr(int value){
		wchar_t str[100] = {0};
        swprintf(str, 99, L"%d", value);
		return str;
	}

	String FCTran::layoutStyleToStr(FCLayoutStyle layoutStyle){
		String str;
        if (layoutStyle == FCLayoutStyle_BottomToTop){
            str = L"BottomToTop";
        }
        else if (layoutStyle == FCLayoutStyle_LeftToRight){
            str = L"LeftToRight";
        }
        else if (layoutStyle == FCLayoutStyle_None){
            str = L"None";
        }
        else if (layoutStyle == FCLayoutStyle_RightToLeft){
            str = L"RightToLeft";
        }
        else if (layoutStyle == FCLayoutStyle_TopToBottom){
            str = L"TopToBottom";
        }
        return str;
	}

	String FCTran::longToStr(Long value){
		wchar_t str[100] = {0};
        swprintf(str, 99, L"%ld", value);
		return str;
	}

	double FCTran::maxValue(double value1, double value2){
        return value1 > value2 ? value1 :  value2;
    }

    double FCTran::minValue(double value1, double  value2){
        return value1 < value2 ? value1 :  value2;
    }

	String FCTran::paddingToStr(const FCPadding& padding){
		wchar_t str[100] = {0};
        swprintf(str, 99, L"%d,%d,%d,%d", padding.left, padding.top, padding.right, padding.bottom);
		return str;
	}

	String FCTran::pointToStr(const FCPoint& mp){
		wchar_t str[100] = {0};
        swprintf(str, 99, L"%d,%d", mp.x, mp.y);
		return str;
	}

	String FCTran::rectToStr(const FCRect& rect){
		wchar_t str[100] = {0};
        swprintf(str, 99, L"%d,%d,%d,%d", rect.left, rect.top, rect.right, rect.bottom);
		return str;
	}

	String FCTran::sizeToStr(const FCSize& size){
		wchar_t str[100] = {0};
        swprintf(str, 99, L"%d,%d", size.cx, size.cy);
		return str;
	}

	FCAnchor FCTran::strToAnchor(const String& str){
		String lowerStr = toLower(str);
		bool left = false, top = false, right = false, bottom = false;
		ArrayList<String> strs = FCTran::split(lowerStr, L",");
		int strSize = (int)strs.size();
		for(int i = 0; i < strSize; i++){
			String str = strs.get(i);
			if(str == L"left"){
				left = true;
			}
			else if(str == L"top"){
				top = true;
			}
			else if(str == L"right"){
				right = true;
			}
			else if(str == L"bottom"){
				bottom =true;
			}
		}
		FCAnchor anchor(left, top, right, bottom);
		return anchor;
	}

	bool FCTran::strToBool(const String& str){
		String lowerStr = toLower(str);
		return lowerStr == L"true" ? true : false;
	}

	Long FCTran::strToColor(const String& str){
		String lowerStr = toLower(str);
	    if (lowerStr == L"empty"){
            return FCColor_None;
        }
		else if (lowerStr == L"none"){
            return FCColor_None;
        }
        else if (lowerStr == L"back"){
            return FCColor_Back;
        }
        else if (lowerStr == L"border"){
            return FCColor_Border;
        }
        else if (lowerStr == L"text"){
            return FCColor_Text;
        }
        else if (lowerStr == L"disabledback"){
            return FCColor_DisabledBack;
        }
        else if (lowerStr == L"disabledtext"){
            return FCColor_DisabledText;
        }
		else{
			if ((int)str.find(L"#") == 0)
            {
				String htmlColor = str.substr(1);
				lstring sHtmlColor = FCTran::StringTostring(htmlColor);
				lstring strR = lstring("0x") + sHtmlColor.substr(0, 2);
				lstring strG = lstring("0x") + sHtmlColor.substr(2, 2);
				lstring strB = lstring("0x") + sHtmlColor.substr(4, 2);
				int r = FCTran::hexToDec(strR.c_str());
				int g = FCTran::hexToDec(strG.c_str());
				int b = FCTran::hexToDec(strB.c_str());
				return FCColor::rgb(r, g, b);
            }
			else if ((int)str.find(L"rgba(") == 0) {
				String strColor = str.substr(5, (int)str.length() - 6);
				ArrayList<String> strs = FCTran::split(strColor, L",");
				int r = _wtoi(strs.get(0).c_str());
				int g = _wtoi(strs.get(1).c_str());
				int b = _wtoi(strs.get(2).c_str());
				int a = _wtoi(strs.get(3).c_str());
				return FCColor::rgba(r, g, b, a);
			}
			else if ((int)str.find(L"rgb(") == 0) {
				String strColor = str.substr(4, (int)str.length() - 5);
				ArrayList<String> strs = FCTran::split(strColor, L",");
				int r = _wtoi(strs.get(0).c_str());
				int g = _wtoi(strs.get(1).c_str());
				int b = _wtoi(strs.get(2).c_str());
				return FCColor::rgb(r, g, b);
			}else
            {
				if(m_htmlColors.size() == 0){
					m_htmlColors.put(L"aliceblue", L"#F0F8FF");
					m_htmlColors.put(L"antiquewhite", L"#FAEBD7");
					m_htmlColors.put(L"aqua", L"#00FFFF");
					m_htmlColors.put(L"aquamarine", L"#7FFFD4");
					m_htmlColors.put(L"azure", L"#F0FFFF");
					m_htmlColors.put(L"beige", L"#F5F5DC");
					m_htmlColors.put(L"bisque", L"#FFE4C4");
					m_htmlColors.put(L"black", L"#000000");
					m_htmlColors.put(L"blanchedalmond", L"#FFEBCD");
					m_htmlColors.put(L"blue", L"#0000FF");
					m_htmlColors.put(L"blueviolet", L"#8A2BE2");
					m_htmlColors.put(L"brown", L"#A52A2A");
					m_htmlColors.put(L"burlywood", L"#DEB887");
					m_htmlColors.put(L"cadetblue", L"#5F9EA0");
					m_htmlColors.put(L"chartreuse", L"#7FFF00");
					m_htmlColors.put(L"chocolate", L"#D2691E");
					m_htmlColors.put(L"coral", L"#FF7F50");
					m_htmlColors.put(L"cornflowerblue", L"#6495ED");
					m_htmlColors.put(L"cornsilk", L"#FFF8DC");
					m_htmlColors.put(L"crimson", L"#DC143C");
					m_htmlColors.put(L"cyan", L"#00FFFF");
					m_htmlColors.put(L"darkblue", L"#00008B");
					m_htmlColors.put(L"darkcyan", L"#008B8B");
					m_htmlColors.put(L"darkgoldenrod", L"#B8860B");
					m_htmlColors.put(L"darkgray", L"#A9A9A9");
					m_htmlColors.put(L"darkgreen", L"#006400");
					m_htmlColors.put(L"darkkhaki", L"#BDB76B");
					m_htmlColors.put(L"darkmagenta", L"#8B008B");
					m_htmlColors.put(L"darkolivegreen", L"#556B2F");
					m_htmlColors.put(L"darkorange", L"#FF8C00");
					m_htmlColors.put(L"darkorchid", L"#9932CC");
					m_htmlColors.put(L"darkred", L"#8B0000");
					m_htmlColors.put(L"darksalmon", L"#E9967A");
					m_htmlColors.put(L"darkseagreen", L"#8FBC8F");
					m_htmlColors.put(L"darkslateblue", L"#483D8B");
					m_htmlColors.put(L"darkslategray", L"#2F4F4F");
					m_htmlColors.put(L"darkturquoise", L"#00CED1");
					m_htmlColors.put(L"darkviolet", L"#9400D3");
					m_htmlColors.put(L"deeppink", L"#FF1493");
					m_htmlColors.put(L"deepskyblue", L"#00BFFF");
					m_htmlColors.put(L"dimgray", L"#696969");
					m_htmlColors.put(L"dodgerblue", L"#1E90FF");
					m_htmlColors.put(L"firebrick", L"#B22222");
					m_htmlColors.put(L"floralwhite", L"#FFFAF0");
					m_htmlColors.put(L"forestgreen", L"#228B22");
					m_htmlColors.put(L"fuchsia", L"#FF00FF");
					m_htmlColors.put(L"gainsboro", L"#DCDCDC");
					m_htmlColors.put(L"ghostwhite", L"#F8F8FF");
					m_htmlColors.put(L"gold", L"#FFD700");
					m_htmlColors.put(L"goldenrod", L"#DAA520");
					m_htmlColors.put(L"gray", L"#808080");
					m_htmlColors.put(L"green", L"#008000");
					m_htmlColors.put(L"greenyellow", L"#ADFF2F");
					m_htmlColors.put(L"honeydew", L"#F0FFF0");
					m_htmlColors.put(L"hotpink", L"#FF69B4");
					m_htmlColors.put(L"indianred", L"#CD5C5C");
					m_htmlColors.put(L"indigo", L"#4B0082");
					m_htmlColors.put(L"ivory", L"#FFFFF0");
					m_htmlColors.put(L"khaki", L"#F0E68C");
					m_htmlColors.put(L"lavender", L"#E6E6FA");
					m_htmlColors.put(L"lavenderblush", L"#FFF0F5");
					m_htmlColors.put(L"lawngreen", L"#7CFC00");
					m_htmlColors.put(L"lemonchiffon", L"#FFFACD");
					m_htmlColors.put(L"lightblue", L"#ADD8E6");
					m_htmlColors.put(L"lightcoral", L"#F08080");
					m_htmlColors.put(L"lightcyan", L"#E0FFFF");
					m_htmlColors.put(L"lightgoldenrodyellow", L"#FAFAD2");
					m_htmlColors.put(L"lightgray", L"#D3D3D3");
					m_htmlColors.put(L"lightgreen", L"#90EE90");
					m_htmlColors.put(L"lightpink", L"#FFB6C1");
					m_htmlColors.put(L"lightsalmon", L"#FFA07A");
					m_htmlColors.put(L"lightseagreen", L"#20B2AA");
					m_htmlColors.put(L"lightskyblue", L"#87CEFA");
					m_htmlColors.put(L"lightslategray", L"#778899");
					m_htmlColors.put(L"lightsteelblue", L"#B0C4DE");
					m_htmlColors.put(L"lightyellow", L"#FFFFE0");
					m_htmlColors.put(L"lime", L"#00FF00");
					m_htmlColors.put(L"limegreen", L"#32CD32");
					m_htmlColors.put(L"linen", L"#FAF0E6");
					m_htmlColors.put(L"magenta", L"#FF00FF");
					m_htmlColors.put(L"maroon", L"#800000");
					m_htmlColors.put(L"mediumaquamarine", L"#66CDAA");
					m_htmlColors.put(L"mediumblue", L"#0000CD");
					m_htmlColors.put(L"mediumorchid", L"#BA55D3");
					m_htmlColors.put(L"mediumpurple", L"#9370DB");
					m_htmlColors.put(L"mediumseagreen", L"#3CB371");
					m_htmlColors.put(L"mediumslateblue", L"#7B68EE");
					m_htmlColors.put(L"mediumspringgreen", L"#00FA9A");
					m_htmlColors.put(L"mediumturquoise", L"#48D1CC");
					m_htmlColors.put(L"mediumvioletred", L"#C71585");
					m_htmlColors.put(L"midnightblue", L"#191970");
					m_htmlColors.put(L"mintcream", L"#F5FFFA");
					m_htmlColors.put(L"mistyrose", L"#FFE4E1");
					m_htmlColors.put(L"moccasin", L"#FFE4B5");
					m_htmlColors.put(L"navajowhite", L"#FFDEAD");
					m_htmlColors.put(L"navy", L"#000080");
					m_htmlColors.put(L"oldlace", L"#FDF5E6");
					m_htmlColors.put(L"olive", L"#808000");
					m_htmlColors.put(L"olivedrab", L"#6B8E23");
					m_htmlColors.put(L"orange", L"#FFA500");
					m_htmlColors.put(L"orangered", L"#FF4500");
					m_htmlColors.put(L"orchid", L"#DA70D6");
					m_htmlColors.put(L"palegoldenrod", L"#EEE8AA");
					m_htmlColors.put(L"palegreen", L"#98FB98");
					m_htmlColors.put(L"paleturquoise", L"#AFEEEE");
					m_htmlColors.put(L"palevioletred", L"#DB7093");
					m_htmlColors.put(L"papayawhip", L"#FFEFD5");
					m_htmlColors.put(L"peachpuff", L"#FFDAB9");
					m_htmlColors.put(L"peru", L"#CD853F");
					m_htmlColors.put(L"pink", L"#FFC0CB");
					m_htmlColors.put(L"plum", L"#DDA0DD");
					m_htmlColors.put(L"powderblue", L"#B0E0E6");
					m_htmlColors.put(L"purple", L"#800080");
					m_htmlColors.put(L"red", L"#FF0000");
					m_htmlColors.put(L"rosybrown", L"#BC8F8F");
					m_htmlColors.put(L"royalblue", L"#4169E1");
					m_htmlColors.put(L"saddlebrown", L"#8B4513");
					m_htmlColors.put(L"salmon", L"#FA8072");
					m_htmlColors.put(L"sandybrown", L"#F4A460");
					m_htmlColors.put(L"seagreen", L"#2E8B57");
					m_htmlColors.put(L"seashell", L"#FFF5EE");
					m_htmlColors.put(L"sienna", L"#A0522D");
					m_htmlColors.put(L"silver", L"#C0C0C0");
					m_htmlColors.put(L"skyblue", L"#87CEEB");
					m_htmlColors.put(L"slateblue", L"#6A5ACD");
					m_htmlColors.put(L"slategray", L"#708090");
					m_htmlColors.put(L"snow", L"#FFFAFA");
					m_htmlColors.put(L"springgreen", L"#00FF7F");
					m_htmlColors.put(L"steelblue", L"#4682B4");
					m_htmlColors.put(L"tan", L"#D2B48C");
					m_htmlColors.put(L"teal", L"#008080");
					m_htmlColors.put(L"thistle", L"#D8BFD8");
					m_htmlColors.put(L"tomato", L"#FF6347");
					m_htmlColors.put(L"turquoise", L"#40E0D0");
					m_htmlColors.put(L"violet", L"#EE82EE");
					m_htmlColors.put(L"wheat", L"#F5DEB3");
					m_htmlColors.put(L"white", L"#FFFFFF");
					m_htmlColors.put(L"whitesmoke", L"#F5F5F5");
					m_htmlColors.put(L"yellow", L"#FFFF00");
					m_htmlColors.put(L"yellowgreen", L"#9ACD32");
				}
				if(m_htmlColors.containsKey(str)){
					String htmlColor = m_htmlColors.get(str).substr(1);
					lstring sHtmlColor = FCTran::StringTostring(htmlColor);
					lstring strR = lstring("0x") + sHtmlColor.substr(0, 2);
					lstring strG = lstring("0x") + sHtmlColor.substr(2, 2);
					lstring strB = lstring("0x") + sHtmlColor.substr(4, 2);
					int r = FCTran::hexToDec(strR.c_str());
					int g = FCTran::hexToDec(strG.c_str());
					int b = FCTran::hexToDec(strB.c_str());
					return FCColor::rgb(r, g, b);
				}else{
					return FCTran::strToLong(str);
				}
            }
		}
	}

	FCContentAlignment FCTran::strToContentAlignment(const String& str){
		String lowerStr = toLower(str);
		FCContentAlignment textAlignment = FCContentAlignment_MiddleCenter;
	    if (lowerStr == L"bottomcenter"){
            textAlignment = FCContentAlignment_BottomCenter;
        }
        else if (lowerStr == L"bottomleft"){
            textAlignment = FCContentAlignment_BottomLeft;
        }
        else if (lowerStr == L"bottomright"){
            textAlignment = FCContentAlignment_BottomRight;
        }
        else if (lowerStr == L"middlecenter"){
            textAlignment = FCContentAlignment_MiddleCenter;
        }
        else if (lowerStr == L"middleleft"){
            textAlignment = FCContentAlignment_MiddleLeft;
        }
        else if (lowerStr == L"middleright"){
            textAlignment = FCContentAlignment_MiddleRight;
        }
        else if (lowerStr == L"topcenter"){
            textAlignment = FCContentAlignment_TopCenter;
        }
        else if (lowerStr == L"topleft"){
            textAlignment = FCContentAlignment_TopLeft;
        }
        else if (lowerStr == L"topright"){
            textAlignment = FCContentAlignment_TopRight;
        }
		return textAlignment;
	}

    FCCursors FCTran::strToCursor(const String& str){
		String lowerStr = toLower(str);
        FCCursors cursor = FCCursors_Arrow;
        if (lowerStr == L"appstarting"){
			cursor = FCCursors_AppStarting;
        }
        else if (lowerStr == L"cross"){
            cursor = FCCursors_Cross;
        }
        else if (lowerStr == L"hand"){
            cursor = FCCursors_Hand;
        }
        else if (lowerStr == L"help"){
            cursor = FCCursors_Help;
        }
        else if (lowerStr == L"ibeam"){
            cursor = FCCursors_IBeam;
        }
        else if (lowerStr == L"no"){
            cursor = FCCursors_No;
        }
        else if (lowerStr == L"sizeall"){
            cursor = FCCursors_SizeAll;
        }
        else if (lowerStr == L"sizenesw"){
            cursor = FCCursors_SizeNESW;
        }
        else if (lowerStr == L"sizens"){
            cursor = FCCursors_SizeNS;
        }
        else if (lowerStr == L"sizenwse"){
            cursor = FCCursors_SizeNWSE;
        }
        else if (lowerStr == L"sizewe"){
            cursor = FCCursors_SizeWE;
        }
        else if (lowerStr == L"uparrow"){
            cursor = FCCursors_UpArrow;
        }
        else if (lowerStr == L"waitcursor"){
            cursor = FCCursors_WaitCursor;
        }
        return cursor;
    }

	FCDockStyle FCTran::strToDock(const String& str){
		String lowerStr = toLower(str);
        FCDockStyle dock = FCDockStyle_None;
        if (lowerStr == L"bottom"){
            dock = FCDockStyle_Bottom;
        }
        else if (lowerStr == L"fill"){
            dock = FCDockStyle_Fill;
        }
        else if (lowerStr == L"left"){
            dock = FCDockStyle_Left;
        }
        else if (lowerStr == L"right"){
            dock = FCDockStyle_Right;
        }
        else if (lowerStr == L"top"){
            dock = FCDockStyle_Top;
        }
        return dock;
    }

	double FCTran::strToDouble(const String& str){
        return wcstod(str.c_str(), 0);
	}

	double FCTran::strToDouble(const wchar_t *str){
        return wcstod(str, 0);
	}

	float FCTran::strToFloat(const String& str){
        return wcstof(str.c_str(), 0);
	}

	FCFont FCTran::strToFont(const String& str){
		ArrayList<String> strs = FCTran::split(str, L",");
		int size = (int)strs.size();
		String fontFamily = L"Default";
		float fontSize = 12;
		bool bold = false;
		bool underline = false;
		bool italic = false;
		bool strikeout = false;
		int angle = 0;
		if(size >= 1){
			fontFamily = strs.get(0);
		}
		if(size >= 2){
			fontSize = (float)_wtof(strs.get(1).c_str());
		}		
		for(int i = 2; i < size; i++){
			String subStr = toLower(strs.get(i));
			if(subStr == L"bold"){
				bold = true;
			}
			else if(subStr == L"underline"){
				underline = true;
			}
			else if(subStr == L"italic"){
				italic = true;
			}
			else if(subStr == L"strikeout"){
				strikeout = true;
			}
			else if((int)subStr.find(L"angle=") == 0){
				angle = FCTran::strToInt(subStr.substr(6));
			}
		}
		FCFont tFont(fontFamily, fontSize, bold, underline, italic, strikeout);	
		tFont.m_angle = angle;
		return tFont;
	}

	FCHorizontalAlign FCTran::strToHorizontalAlign(const String& str){
		String lowerStr = toLower(str);
	    FCHorizontalAlign horizontalAlign = FCHorizontalAlign_Center;
        if (lowerStr == L"right"){
            horizontalAlign = FCHorizontalAlign_Right;
        }
		else if(lowerStr == L"inherit"){
			horizontalAlign = FCHorizontalAlign_Inherit;
		}
        else if (lowerStr == L"left"){
            horizontalAlign = FCHorizontalAlign_Left;
        }
        return horizontalAlign;
	}

	int FCTran::strToInt(const String& str){
        return wcstol(str.c_str(), 0, 0);
	}

	int FCTran::strToInt(const wchar_t *str){
        return wcstol(str, 0, 0);
	}

	FCLayoutStyle FCTran::strToLayoutStyle(const String& str){
		String lowerStr = toLower(str);
        FCLayoutStyle layoutStyle = FCLayoutStyle_None;
        if (lowerStr == L"bottomtotop"){
            layoutStyle = FCLayoutStyle_BottomToTop;
        }
        else if (lowerStr == L"lefttoright"){
            layoutStyle = FCLayoutStyle_LeftToRight;
        }
        else if (lowerStr == L"righttoleft"){
            layoutStyle = FCLayoutStyle_RightToLeft;
        }
        else if (lowerStr == L"toptobottom"){
            layoutStyle = FCLayoutStyle_TopToBottom;
        }
        return layoutStyle;
    }

	Long FCTran::strToLong(const String& str){
        return wcstod(str.c_str(), 0);
	}

	Long FCTran::strToLong(const wchar_t *str){
        return wcstol(str, 0, 0);
	}

	FCPadding FCTran::strToPadding(const String& str){
        int left = 0, top = 0, right = 0, bottom = 0;
        if((int)str.find(L",") != -1){
            ArrayList<String> strs = FCTran::split(str, L",");
            if(strs.size() == 4){
                left = strToInt(strs.get(0));
                top = strToInt(strs.get(1));
                right = strToInt(strs.get(2));
                bottom = strToInt(strs.get(3));
            }
        }else if((int)str.find(L" ") != -1){
            ArrayList<String> strs = FCTran::split(str, L" ");
            if(strs.size() == 4){
                left = strToInt(strs.get(0));
                top = strToInt(strs.get(1));
                right = strToInt(strs.get(2));
                bottom = strToInt(strs.get(3));
            }
        }
        FCPadding padding(left, top, right, bottom);
        return padding;
	}

	FCPoint FCTran::strToPoint(const String& str){
        int x = 0, y = 0;
        if((int)str.find(L",") != -1){
            ArrayList<String> strs = FCTran::split(str, L",");
            if(strs.size() == 2){
                x = strToInt(strs.get(0));
                y = strToInt(strs.get(1));
            }
        }else if((int)str.find(L" ") != -1){
            ArrayList<String> strs = FCTran::split(str, L" ");
            if(strs.size() == 2){
                x = strToInt(strs.get(0));
                y = strToInt(strs.get(1));
            }
        }
        FCPoint mp ={x, y};
        return mp;
	}

	FCRect FCTran::strToRect(const String& str){
        int left = 0, top = 0, right = 0, bottom = 0;
        if((int)str.find(L",") != -1){
            ArrayList<String> strs = FCTran::split(str, L",");
            if(strs.size() == 4){
                left = strToInt(strs.get(0));
                top = strToInt(strs.get(1));
                right = strToInt(strs.get(2));
                bottom = strToInt(strs.get(3));
            }
        }else if((int)str.find(L" ") != -1){
            ArrayList<String> strs = FCTran::split(str, L" ");
            if(strs.size() == 4){
                left = strToInt(strs.get(0));
                top = strToInt(strs.get(1));
                right = strToInt(strs.get(2));
                bottom = strToInt(strs.get(3));
            }
        }
        FCRect rect ={left, top, right, bottom};
        return rect;
	}

	FCSize FCTran::strToSize(const String& str){
        int cx = 0, cy = 0;
        if((int)str.find(L",") != -1){
            ArrayList<String> strs = FCTran::split(str, L",");
            if(strs.size() == 2){
                cx = strToInt(strs.get(0));
                cy = strToInt(strs.get(1));
            }
        }else if((int)str.find(L" ") != -1){
            ArrayList<String> strs = FCTran::split(str, L" ");
            if(strs.size() == 2){
                cx = strToInt(strs.get(0));
                cy = strToInt(strs.get(1));
            }
        }
        FCSize size ={cx, cy};
        return size;
	}

	FCVerticalAlign FCTran::strToVerticalAlign(const String& str){
		String lowerStr = toLower(str);
        FCVerticalAlign verticalAlign = FCVerticalAlign_Middle;
        if (str == L"bottom"){
            verticalAlign = FCVerticalAlign_Bottom;
        }
        else if (str == L"inherit"){
            verticalAlign = FCVerticalAlign_Inherit;
        }
        else if (str == L"top"){
            verticalAlign = FCVerticalAlign_Top;
        }
        return verticalAlign;
	}

	String FCTran::verticalAlignToStr(FCVerticalAlign verticalAlign){
		String str;
        if (verticalAlign == FCVerticalAlign_Bottom){
            str = L"Bottom";
        }
        else if (verticalAlign == FCVerticalAlign_Inherit){
            str = L"Inherit";
        }
        else if (verticalAlign == FCVerticalAlign_Middle){
            str = L"Middle";
        }
        else if (verticalAlign == FCVerticalAlign_Top){
            str = L"Top";
        }
        return str;
	}

	inline int isLeapYear(int year){
        return( (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0));
    }
    
    const int evenyMonths[2][12] = {{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
    };
    
    double FCTran::getDateNum(int tm_year, int tm_mon, int tm_mday, int tm_hour, int tm_min, int tm_sec, int tm_msec){
        double tn = 0;
        if ((tm_mon -= 2) <= 0){
            tm_mon += 12;
            tm_year -= 1;
        }
        double year = tm_year / 4 - tm_year / 100 + tm_year / 400 + 367 * tm_mon / 12 + tm_mday;
        double month = tm_year * 365 - 719499;
        tn = ((year + month) * 24 * 60 * 60) + tm_hour * 3600 + tm_min * 60 + tm_sec;
        return (double)((long long)tn + tm_msec / 1000);
    }
    
    void FCTran::getDateByNum(double num, int *tm_year, int *tm_mon, int *tm_mday, int *tm_hour, int *tm_min, int *tm_sec, int *tm_msec){
        long tn = (long)num;
        int dayclock = (int)(tn % 86400);
        int dayno = (int)(tn / 86400);
        int year = 1970;
        *tm_sec = dayclock % 60;
        *tm_min = (dayclock % 3600) / 60;
        *tm_hour = dayclock / 3600;
        int yearSize = 0;
        while (dayno >= (yearSize = (isLeapYear(year) == 1 ? 366 : 365))){
            dayno -= yearSize;
            year++;
        }
        *tm_year = year;
        int month = 0;
        while (dayno >= evenyMonths[isLeapYear(year)][month]){
            dayno -= evenyMonths[isLeapYear(year)][month];
            month++;
        }
        *tm_mon = month + 1;
        *tm_mday = dayno + 1;
        *tm_msec = (long)((num * 1000 - floor(num) * 1000));
    }

	String FCTran::getFormatDate(double date){
        wchar_t str[1024] = {0};
        int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, msecond = 0;
        getDateByNum(date, &year, &month, &day, &hour, &minute, &second, &msecond);
        if(hour != 0){
            swprintf(str, 99, L"%02d:%02d", hour, minute);
        }
        else{
            swprintf(str, 99, L"%d-%02d-%02d", year, month, day);
        }
        return str;
	}

	String FCTran::getFormatDate(const String& format, int year, int month, int day, int hour, int minute, int second){
        String strDate = format;
        wchar_t sz[100] ={0};
        swprintf(sz, 99, L"%d", year);
        String strYear = sz;
        memset(sz, '\0', 100);
        swprintf(sz, 99, L"%02d", month);
        String strMonth = sz;
        memset(sz, '\0', 100);
        swprintf(sz, 99, L"%02d", day);
        String strDay = sz;
        memset(sz, '\0', 100);
        swprintf(sz, 99, L"%02d", hour);
        String strHour = sz;
        memset(sz, '\0', 100);
        swprintf(sz, 99, L"%02d", minute);
        String strMinute = sz;
        memset(sz, '\0', 100);
        swprintf(sz, 99, L"%02d", second);
        String strSecond = sz;
        if((int)format.find(L"yyyy") != -1){
            strDate = FCTran::replace(strDate, L"yyyy", strYear);
        }
        if((int)format.find(L"MM") != -1){
            strDate = FCTran::replace(strDate, L"MM", strMonth);
        }
        if((int)format.find(L"dd") != -1){
            strDate = FCTran::replace(strDate, L"dd", strDay);
        }
        if((int)format.find(L"HH") != -1){
            strDate = FCTran::replace(strDate, L"HH", strHour);
        }
        if((int)format.find(L"mm") != -1){
            strDate = FCTran::replace(strDate, L"mm", strMinute);
        }
        if((int)format.find(L"ss") != -1){
            strDate = FCTran::replace(strDate, L"ss", strSecond);
        }
        return strDate;
	}

	String FCTran::getValueByDigit(double value, int digit){
        wchar_t str[1024] = {0};
       if(!isnan(value)){
           if(digit == 0){
               double newValue = round(value);
               if(abs(value - newValue) < 1){
                   value = newValue;
               }
           }
           switch(digit){
               case 0:
                   swprintf(str, 99, L"%d", (int)value);
                   break;
               case 1:
                   swprintf(str, 99, L"%.1f", value);
                   break;
               case 2:
                   swprintf(str, 99, L"%.2f", value);
                   break;
               case 3:
                   swprintf(str, 99, L"%.3f", value);
                   break;
               case 4:
                   swprintf(str, 99, L"%.4f", value);
                   break;
               case 5:
                   swprintf(str, 99, L"%.5f", value);
                   break;
               case 6:
                   swprintf(str, 99, L"%.6f", value);
                   break;
               case 7:
                   swprintf(str, 99, L"%.7f", value);
                   break;
               case 8:
                   swprintf(str, 99, L"%.8f", value);
                   break;
               case 9:
                   swprintf(str, 99, L"%.9f", value);
                   break;
               default:
                   swprintf(str, 99, L"%f", value);
           }
       }
       return str;
	}

	int FCTran::hexToDec(const char *str){
		bool IsHex = false;
		int result = 0;
		int i = 0, szLen = 0, nHex;
		if(str[0] == '0'){
			if((str[1] == 'x') || (str[1] == 'X')){
				IsHex = true;
				i = 2;
			}
		}
	    szLen = strlen(str);
	    nHex = '0';
	    for (; i < szLen; i++){
			if(IsHex){
				if ((str[i] >= '0') && (str[i] <= '9')){
					nHex = '0';
				}
				else if ((str[i] >= 'A') && (str[i] <= 'F')){
					nHex = 'A' - 10;
				}
		        else if ((str[i] >= 'a') && (str[i] <= 'f')){
					nHex = 'a' - 10;
				}
				else{
					return 0;
				}
				result = result * 16 + str[i] - nHex;
			}
			else{
				if ((str[i] < '0') || (str[i] > '9')){
					return 0;
				}
				result = result * 10 + str[i] - nHex;
			}
		}
		return result;
	}

	lstring FCTran::replace(const lstring& str, const lstring& src, const lstring& dest)
	{
		lstring newStr = str;
		#ifdef USEFCSTRING
			newStr.replace(src, dest);
		#else                                                                            
			lstring::size_type pos = 0;
			while( (pos = newStr.find(src, pos)) != lstring::npos )
			{
				newStr.replace(pos, (int)src.length(), dest);
				pos += (int)dest.length();
			}
		#endif
		return newStr;
	}

	String FCTran::replace(const String& str, const String& src, const String& dest){
		String newStr = str;
		#ifdef USEFCSTRING
			newStr.replace(src, dest);
		#else                                                                            
			String::size_type pos = 0;
			while( (pos = newStr.find(src, pos)) != lstring::npos ){
				newStr.replace(pos, (int)src.length(), dest);
				pos += (int)dest.length();
			}
		#endif
		return newStr;
	}

	float FCTran::safeDoubleToFloat(double value, int digit){
		return strToFloat(getValueByDigit(value, digit));
	}

	String FCTran::toLower(const String& str){
		String lowerStr = str;
		#ifdef USEFCSTRING
            lowerStr.toLower();
        #else
            std::transform(lowerStr.begin(), lowerStr.end(), lowerStr.begin(), [](unsigned char c){return std::tolower(c);});
		#endif
		return lowerStr;
	}

	String FCTran::toUpper(const String& str){
		String upperStr = str;
		#ifdef USEFCSTRING
            upperStr.toUpper();
        #else
            std::transform(upperStr.begin(), upperStr.end(), upperStr.begin(), [](unsigned char c){return std::toupper(c);});
		#endif
		return upperStr;
	}

	StringBuilder::StringBuilder(){
        
    }

    StringBuilder::~StringBuilder(){
        m_strs.clear();
    }

    void StringBuilder::append(const String& str){
        m_strs.add(str);
    }

    void StringBuilder::appendLine(const String& str){
        m_strs.add(str + L"\r\n");
    }

    void StringBuilder::clear(){
        m_strs.clear();
    }

    String StringBuilder::toString(){
        String str;
        int totalSize = 0;
        for(int i = 0; i < m_strs.size(); i++){
            totalSize += m_strs.get(i).length();
        }
        if(totalSize > 0){
            wchar_t *sz = new wchar_t[totalSize + 1];
            memset(sz, '\0', totalSize + 1);
            int pos = 0;
            for(int i = 0; i < m_strs.size(); i++){
                String subStr = m_strs.get(i);
                int subStrLen = (int)subStr.length();
                for(int j = 0; j < subStrLen; j++){
                    sz[pos + j] = subStr[j];
                }
                pos += subStrLen;
            }
            str = String(sz);
            delete[] sz;
            sz = 0;
        }
        return str;
    }
}
